/*
 * <h3>Title:wheel-parent系统</h3>
 * <p>Copyright (c) 2020, wnfbx@163.com. All rights reserved.</p>
 * @author wnfbx@163.com
 */
package com.wheel.autoconfigure.dynamicdatasource.aop;

import com.wheel.autoconfigure.dynamicdatasource.annotation.DynamicDataSourceKey;
import com.wheel.autoconfigure.dynamicdatasource.builder.DynamicDataSourceBuilder;
import com.wheel.autoconfigure.dynamicdatasource.datasource.DynamicRoutingDataSource;
import com.wheel.autoconfigure.dynamicdatasource.processor.DynamicDataSourceDetermineProcessor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Method;

/**
 * <dt>Description:DynamicDataSourceAnnotationInterceptor</dt>
 * <dd>动态数据源注解方法拦截器
 * <p>数据源切换及负载都是此处处理</p></dd>
 *
 * @author wnfbx@163.com
 * @version 1.0 <i>2020/1/4 18:28</i>
 * @since jdk1.7+
 */
public class DynamicDataSourceAnnotationInterceptor implements MethodInterceptor {

    private DynamicDataSourceDetermineProcessor processor;

    public DynamicDataSourceAnnotationInterceptor(DynamicDataSourceBuilder dynamicDataSourceBuilder) {
        processor = dynamicDataSourceBuilder.getDetermineProcessor();
    }


    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        try {
            DynamicRoutingDataSource.push(determineDatasource(invocation));
            return invocation.proceed();
        } finally {
            DynamicRoutingDataSource.poll();
        }
    }

    private String determineDatasource(MethodInvocation invocation) {
        Method method = invocation.getMethod();
        //方法上有注解
        DynamicDataSourceKey dynamicDataSourceKey = null;
        if (method.isAnnotationPresent(DynamicDataSourceKey.class)) {
            dynamicDataSourceKey = method.getAnnotation(DynamicDataSourceKey.class);
        }
        //获取类上的注解
        else if (method.getDeclaringClass().isAnnotationPresent(DynamicDataSourceKey.class)) {
            dynamicDataSourceKey = method.getDeclaringClass().getAnnotation(DynamicDataSourceKey.class);
        }
        return processor.process(dynamicDataSourceKey);
    }
}
